Skip to content

VAULT-1564 report in-flight requests#13024

Merged
hghaf099 merged 36 commits intomainfrom
report-in-flight-req
Dec 8, 2021
Merged

VAULT-1564 report in-flight requests#13024
hghaf099 merged 36 commits intomainfrom
report-in-flight-req

Conversation

@hghaf099
Copy link
Copy Markdown
Contributor

@hghaf099 hghaf099 commented Nov 3, 2021

Adding a trace capability to the request handling or HTTP layer that shows, for each requests received but not yet answered:

  • time duration since the request was received
  • the request RemoteAddress
  • the operation and path in the request, but not payload

This would provide a point-in-time snapshot of what user requests Vault is handling, highlighting any deadlocks or abnormally long response times.

The API reporting on this information should be called as part of the debug command. It also support unauthenticated requests if a new profiling config option is set.

Adding a new metric for the total number of in-flight requests.
Adding documentation for the metric and the new endpoint.

Here is a sample result:
{ "7ecdd692-d934-e668-365d-b4a6664e1548": { "start_time": "2021-11-03T14:54:45.774893-07:00", "client_remote_address": "127.0.0.2:53771", "request_path": "/v1/secret/data/68", "duration": "230750 microseconds" } }

@vercel vercel bot temporarily deployed to Preview – vault November 3, 2021 00:38 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook November 3, 2021 00:38 Inactive
@vercel vercel bot temporarily deployed to Preview – vault November 3, 2021 00:55 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook November 3, 2021 00:55 Inactive
@vercel vercel bot temporarily deployed to Preview – vault November 3, 2021 00:57 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook November 3, 2021 00:57 Inactive
@vercel vercel bot temporarily deployed to Preview – vault November 3, 2021 20:38 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook November 3, 2021 20:38 Inactive
@hghaf099 hghaf099 requested a review from ncabatoff November 3, 2021 22:38
@vercel vercel bot temporarily deployed to Preview – vault November 5, 2021 00:21 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook November 5, 2021 00:21 Inactive
@hghaf099 hghaf099 marked this pull request as ready for review November 5, 2021 00:21
@hghaf099 hghaf099 requested a review from taoism4504 as a code owner November 5, 2021 00:21
@hghaf099 hghaf099 requested a review from ncabatoff November 5, 2021 01:01
command/debug.go Outdated
healthInfo, err := c.cachedClient.Sys().Health()
if err != nil {
c.captureError("server-status.health", err)
return
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it's true that an error on the health endpoint will probably mean one on the seal-status endpoint too, I'd rather we didn't assume that. Can you revert this change please?

command/debug.go Outdated
sealInfo, err := c.cachedClient.Sys().SealStatus()
if err != nil {
c.captureError("server-status.seal", err)
return
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too.

command/debug.go Outdated
defer resp.Body.Close()
err = jsonutil.DecodeJSONFromReader(resp.Body, &data)
if err != nil {
c.captureError("inFlightReq-status", err)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the first arg to captureError is the target, which we're now calling requests right?

command/debug.go Outdated
return
}

if data != nil && len(data) > 0 {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this conditional do we?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, there should always be at least one entry which is the /v1/sys/in-flight-req related info

http/handler.go Outdated
ClientRemoteAddr: r.RemoteAddr,
ReqPath: r.URL.Path,
})
if err != nil {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What error are we handling here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thanks for catching this!

@vercel vercel bot temporarily deployed to Preview – vault December 6, 2021 19:55 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook December 6, 2021 19:55 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook December 6, 2021 21:04 Inactive
@vercel vercel bot temporarily deployed to Preview – vault December 6, 2021 21:04 Inactive
@vercel vercel bot temporarily deployed to Preview – vault December 6, 2021 21:06 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook December 6, 2021 21:06 Inactive
@vercel vercel bot temporarily deployed to Preview – vault December 6, 2021 21:36 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook December 6, 2021 21:36 Inactive
vault/core.go Outdated
}

type InFlightRequests struct {
l sync.RWMutex
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like us to avoid having both a mutex and sync.Map; if we're going to use a mutex to guard the map, we may as well just use a regular map, since it's way cheaper than sync.Map if concurrent access is protected otherwise.

That said, I think you could get rid of the lock if you stored InFlightReqData instead of *InflightReqData. The race occurs when we try to update data referenced by a pointer while another goroutine is trying to load the data. If instead updating consists of copying the data out of the map, updating that copy, then storing a copy back into the map, I don't think it'll be racy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

going to remove the mutex.

vault/testing.go Outdated

func TestCoreWithCustomResponseHeaderAndUI(t testing.T, CustomResponseHeaders map[string]map[string]string, enableUI bool) (*Core, [][]byte, string) {
confRaw := &server.Config{
LogRequestsLevel: "basic",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a valid log level, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I wanted to make sure invalid values are not translated to valid ones

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we probably shouldn't do that kind of thing outside of a test specific to the feature. Unless it's somehow relevant to custom response header behaviour?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, make sense.

@vercel vercel bot temporarily deployed to Preview – vault-storybook December 7, 2021 17:00 Inactive
@vercel vercel bot temporarily deployed to Preview – vault December 7, 2021 17:00 Inactive
@hghaf099 hghaf099 requested a review from ncabatoff December 7, 2021 18:13
vault/core.go Outdated
currentInFlightReqMap := make(map[string]InFlightReqData)
c.inFlightReqData.InFlightReqMap.Range(func(key, value interface{}) bool {
// there is only one writer to this map, so skip checking for errors
v, _ := value.(InFlightReqData)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit, but: by using the two-argument form, you're deliberately ignoring errors. Either we don't believe errors are possible, in which case you can use the single-argument form which panics on error, or we do, in which case we should handle the error.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think at some point, you mentioned that there is only one writer for this and there is no need to check if the assertion worked or not. The comment I have on line 3006 talks about that. But, happy to add the error check for this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with there being no error check, I'm just saying if we're not going to check for errors because we think they can't happen, why not use the single-argument form? If we're right that errors can't happen, then they're equivalent. If we're wrong, we'll learn of it because of panics.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! I think it is highly unlikely that a panic happens. I am going to use the single-arguments form.

@vercel vercel bot temporarily deployed to Preview – vault-storybook December 7, 2021 21:55 Inactive
@vercel vercel bot temporarily deployed to Preview – vault December 7, 2021 21:55 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants